package com.accelstack.cmp.controller;

import com.accelstack.cmp.dto.AuthRequest;
import com.accelstack.cmp.dto.AuthResponse;
import com.accelstack.cmp.security.SessionService;
import com.accelstack.cmp.security.TokenManager;
import com.accelstack.cmp.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * 认证控制器
 * 
 * 认证流程：
 * 1. 登录时使用AK/SK验证身份
 * 2. 验证成功后生成Token并存储到Redis
 * 3. 返回Token给客户端
 * 4. 后续所有API请求只需在请求头中携带 x-auth-token
 * 5. Token有效期24小时，每次访问自动刷新
 */
@Slf4j
@Tag(name = "认证管理", description = "用户认证相关接口")
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class AuthController {
    
    private final UserService userService;
    private final SessionService sessionService;
    private final TokenManager tokenManager;
    
    @Operation(summary = "AK/SK认证", description = "使用AccessKey和SecretKey进行认证，返回Token")
    @PostMapping("/login")
    public ResponseEntity<AuthResponse> login(@RequestBody AuthRequest request, HttpServletRequest httpRequest) {
        
        // 验证AK/SK
        boolean valid = userService.validateCredentials(
            request.getAccessKey(), 
            request.getSecretKey()
        );
        
        if (!valid) {
            return ResponseEntity.status(401)
                .body(AuthResponse.builder()
                    .tokenType("Error")
                    .username("认证失败")
                    .build());
        }
        
        // 获取用户信息并生成Token
        return userService.findByAccessKey(request.getAccessKey())
            .map(user -> {
                // 生成Token（存储在Redis中）
                String token = tokenManager.generateToken(user.getUsername(), user.getAccessKey());
                
                // 创建Session（用于额外的用户信息存储）
                sessionService.createSession(httpRequest, user);
                
                // 更新最后登录信息
                userService.updateLastLogin(
                    user.getAccessKey(), 
                    httpRequest.getRemoteAddr()
                );
                
                AuthResponse response = AuthResponse.builder()
                    .token(token)
                    .tokenType("Token")
                    .username(user.getUsername())
                    .accessKey(user.getAccessKey())
                    .expiresIn(86400000L) // 24小时
                    .build();
                
                log.info("用户登录成功 - 用户名: {}, IP: {}", user.getUsername(), httpRequest.getRemoteAddr());
                
                return ResponseEntity.ok(response);
            })
            .orElse(ResponseEntity.status(401).build());
    }
    
    @Operation(summary = "刷新Token", description = "延长当前Token的有效期")
    @PostMapping("/refresh")
    public ResponseEntity<Map<String, Object>> refreshToken(
            @RequestHeader("x-auth-token") String token) {
        
        if (!tokenManager.validateToken(token)) {
            return ResponseEntity.status(401).build();
        }
        
        boolean refreshed = tokenManager.refreshToken(token);
        if (!refreshed) {
            return ResponseEntity.status(401).build();
        }
        
        Long ttl = tokenManager.getTokenTTL(token);
        String username = tokenManager.getUsernameFromToken(token);
        
        Map<String, Object> result = new HashMap<>();
        result.put("message", "Token已刷新");
        result.put("username", username);
        result.put("ttl", ttl);
        result.put("expiresIn", ttl * 1000);
        
        return ResponseEntity.ok(result);
    }
    
    @Operation(summary = "登出", description = "删除当前Token并销毁Session")
    @PostMapping("/logout")
    public ResponseEntity<String> logout(
            @RequestHeader(value = "x-auth-token", required = false) String token,
            HttpServletRequest httpRequest) {
        
        // 删除Token
        if (token != null) {
            tokenManager.deleteToken(token);
        }
        
        // 销毁Session
        sessionService.destroySession(httpRequest);
        
        return ResponseEntity.ok("登出成功");
    }
    
    @Operation(summary = "验证认证状态", description = "检查当前认证是否有效")
    @GetMapping("/validate")
    public ResponseEntity<String> validate() {
        return ResponseEntity.ok("认证有效");
    }
}

